package cn.com.surker.wechat;

import cn.com.surker.common.HttpRequestHelper;
import cn.com.surker.redis.RedisUtils;
import cn.com.surker.spring.SpringContextHolder;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @Author lucky
 * @create 2022年02月15 9:32
 * @desc 微信公众号工具类
 */
@Slf4j
public class WechatAccountApi {
    /***微信公众号APPID***/
    public static String account_appid = "wx2e0f397328100edb";
    /**微信公众号授权密匙***/
    public static String account_secret = "1a05e0c55524e3df44db41d5b9c878fe";
    /**缓存键**/
    public static String accessTokenKey = "account_surker_cloud_access_token";
    /**网页授权token**/
    public static String webAccessTokenKey = "web_account_surker_cloud_access_token";
    /**缓存键**/
    public static String ticketKey = "account_surker_cloud_js_ticket";
    /**缓存时间**/
    public static Long sessionExpired = 7200L;

    /**无人过磅完成消息模板***/
    public static String finishTemplateId = "tCzdcYlyxgc99p-0Zo3phGkZ7tAmDD9ZWwXOSXjKYHI";

    /**无人过磅重磅完成消息模板***/
    public static String weightFinishTemplateId = "9bkLeYVLRoEyp2oN-eW47vd8QpmPJ7P-zlgfkma1bEU";
    /**工地下单审核完成通知模板***/
    public static String clientFinishTemplateId = "Ccc7FdMxuUlNz90zbMorVN7bN8G5wd0HZCCBhreaCbI";

    public static void main(String[] args){
//        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + account_appid + "&secret=" + account_secret;
//        try {
//            String res = HttpRequestHelper.get(url);
//            JSONObject obj = JSONObject.parseObject(res);
//            System.out.println(obj);
//        } catch (Exception e) {
//            log.error("获取微信公众号API token失败：" + e.getMessage(), e);
//        }
        List<String> keyList = new ArrayList<>();
        List<String> valueList = new ArrayList<>();
        keyList.add("character_string13");
        keyList.add("thing14");
        keyList.add("thing15");
        keyList.add("thing9");
        keyList.add("time7");

        valueList.add("RW-2022-1215");
        valueList.add("陶家隧道工程一标段");
        valueList.add("浇筑部位AA");
        valueList.add("183方|C30898|220+20");
        valueList.add("2024-03-04 15:12");
        sendWehcatOrderMessage("o-m1vwRhqGMELBoVk1GRXTCcwjJA", clientFinishTemplateId, keyList, valueList, "http://www.baidu.com");
//        JSONObject json1 = new JSONObject();
//        JSONObject keyJson = new JSONObject();
//        keyJson.put("value", "重磅过磅完成通知");
//        keyJson.put("color", "#173177");
//        json1.put("first", keyJson);
//
//        JSONObject keyJson1 = new JSONObject();
//        keyJson1.put("value", "重庆神赞建材有限公司");
//        keyJson1.put("color", "#173177");
//        json1.put("keyword1", keyJson1);
//
//        JSONObject keyJson2 = new JSONObject();
//        keyJson2.put("value", "MS-BBYB20-0914-025");
//        keyJson2.put("color", "#173177");
//        json1.put("keyword2", keyJson2);
//
//        JSONObject keyJson3 = new JSONObject();
//        keyJson3.put("value", "测试11");
//        keyJson3.put("color", "#173177");
//        json1.put("keyword3", keyJson3);
//
//        JSONObject keyJson4 = new JSONObject();
//        keyJson4.put("value", "毛重:56.8吨");
//        keyJson4.put("color", "#173177");
//        json1.put("keyword4", keyJson4);
//
//        JSONObject keyJson5 = new JSONObject();
//        keyJson5.put("value", DateUtil.convertString(new Date()));
//        keyJson5.put("color", "#173177");
//        json1.put("keyword5", keyJson5);
//
//
//        JSONObject keyJson6 = new JSONObject();
//        keyJson6.put("value", "您驾驶的渝ART673正在配送的山碎石[0-1],已完成重磅称重,感谢贵公司的配合,请注意留底和查询使用");
//        keyJson6.put("color", "#ED5024");
//        json1.put("remark", keyJson6);
//
//        JSONObject json2 = new JSONObject();
//        JSONObject keyJson11 = new JSONObject();
//        keyJson11.put("value", "送货过磅完成通知");
//        keyJson11.put("color", "#173177");
//        json2.put("first", keyJson11);
//
//        JSONObject keyJson12 = new JSONObject();
//        keyJson12.put("value", "渝ART673");
//        keyJson12.put("color", "#173177");
//        json2.put("keyword1", keyJson12);
//
//        JSONObject keyJson13 = new JSONObject();
//        keyJson13.put("value", "重庆神赞建材有限公司");
//        keyJson13.put("color", "#173177");
//        json2.put("keyword2", keyJson13);
//
//        JSONObject keyJson14 = new JSONObject();
//        keyJson14.put("value", "MS-BBYB20-0914-025");
//        keyJson14.put("color", "#173177");
//        json2.put("keyword3", keyJson14);
//
//        JSONObject keyJson15 = new JSONObject();
//        keyJson15.put("value", "山碎石[0-1]");
//        keyJson15.put("color", "#173177");
//        json2.put("keyword4", keyJson15);
//
//        JSONObject keyJson16 = new JSONObject();
//        keyJson16.put("value", "6.8吨、56.8吨、36.8吨");
//        keyJson16.put("color", "#173177");
//        json2.put("keyword5", keyJson16);
//
//        JSONObject keyJson17 = new JSONObject();
//        keyJson17.put("value", "尊敬的某某某师傅,感谢贵公司的配合,请注意留底和查询使用");
//        keyJson17.put("color", "#ED5024");
//        json2.put("remark", keyJson17);
//
//        sendWaringServiceMessage("o-m1vwRhqGMELBoVk1GRXTCcwjJA", "String title",  "String content",
//                "#2A82E4", "String remark",  "String detailUrl");
//        sendWeightErrorMessage("o-m1vwRhqGMELBoVk1GRXTCcwjJA", "title", "A12345", "business",
//                "aaa-line-444",  "weight", "remark");
    }


    /**
     * 发送微信小程序过磅文本消息(服务模板)
     * @param openid openid
     * @param title 标题
     * @param remark 备注
     * @return
     */
    public static Integer sendWeightMessage(String openid, String title, String carNo, String supplier,
                                                        String orderId, String material, String weight, String remark) {
//        String token = "72_giYGCWYb9n2MwNrvfYrDDmRCBToIDsoRl4JLICYknLuZrWM1gEOpRphTJ1cHYQ5UTEzKieAV6YaGHdz1biUodBGWRYEiymSFUPMv0uGtV1VWr9ebny16RKlPmloDYZeAHAVQR";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String openUrl = "https://weight.chixugroup.com/cloud/weight-detail?openid=" + openid + "&orderId=" + orderId;
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
        json.put("template_id", "tCzdcYlyxgc99p-0Zo3phGkZ7tAmDD9ZWwXOSXjKYHI");
        if (!StringUtils.isNull(openUrl))
            json.put("url", openUrl);
        else
            json.put("url", "http://weixin.qq.com/download");

        if (!StringUtils.isNull(supplier) && supplier.length() > 20)
            supplier = supplier.substring(0, 20);
        if (!StringUtils.isNull(material) && material.length() > 20)
            material = material.substring(0, 20);
        if (!StringUtils.isNull(orderId) && orderId.length() > 20)
            orderId = orderId.substring(0, 20);
        if (!StringUtils.isNull(weight) && weight.length() > 20)
            weight = weight.substring(0, 20);

        JSONObject first = new JSONObject();
        first.put("value", title);
        first.put("color", "#2A82E4");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", carNo + "(" + DateUtil.convertString(new Date(), "HH时mm分") + ")");
        keyword1.put("color", "#2A82E4");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", supplier);
        keyword2.put("color", "#2A82E4");
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", orderId);
        keyword3.put("color", "#2A82E4");
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", material);
        keyword4.put("color", "#2A82E4");
        JSONObject keyword5 = new JSONObject();
        keyword5.put("value", weight);
        keyword5.put("color", "#2A82E4");
        JSONObject remarkJson = new JSONObject();
        remarkJson.put("value", remark);
        remarkJson.put("color", "#ED5024");
        JSONObject data = new JSONObject();
        data.put("first", first);
        data.put("keyword1", keyword1);
        data.put("keyword2", keyword2);
        data.put("keyword3", keyword3);
        data.put("keyword4", keyword4);
        data.put("keyword5", keyword5);
        data.put("remark", remarkJson);

        json.put("access_token", token);
        json.put("touser", openid);
        json.put("data", data);
//        json.put("access_token", token);
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            log.error("-----发送微信小程序过磅文本消息完成-------：" + res);
            if(obj.getInteger("errcode") == 0){//成功
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 42001 || obj.getInteger("errcode") == 40001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendWeightMessage(openid, title, carNo, supplier, orderId, material, weight, remark);
            } else {
                log.error("发送微信小程序过磅文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序过磅文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }
    public static Integer sendWeightMessageV1(String openid, String title, String carNo, String supplier,
                                            String orderId, String material, String weight, String remark) {
//        String token = "72_giYGCWYb9n2MwNrvfYrDDmRCBToIDsoRl4JLICYknLuZrWM1gEOpRphTJ1cHYQ5UTEzKieAV6YaGHdz1biUodBGWRYEiymSFUPMv0uGtV1VWr9ebny16RKlPmloDYZeAHAVQR";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String openUrl = "https://weight.chixugroup.com/cloud-v1/weight-detail?openid=" + openid + "&orderId=" + orderId;
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
        json.put("template_id", "tCzdcYlyxgc99p-0Zo3phGkZ7tAmDD9ZWwXOSXjKYHI");
        if (!StringUtils.isNull(openUrl))
            json.put("url", openUrl);
        else
            json.put("url", "http://weixin.qq.com/download");

        if (!StringUtils.isNull(supplier) && supplier.length() > 20)
            supplier = supplier.substring(0, 20);
        if (!StringUtils.isNull(material) && material.length() > 20)
            material = material.substring(0, 20);
        if (!StringUtils.isNull(orderId) && orderId.length() > 20)
            orderId = orderId.substring(0, 20);
        if (!StringUtils.isNull(weight) && weight.length() > 20)
            weight = weight.substring(0, 20);

        JSONObject first = new JSONObject();
        first.put("value", title);
        first.put("color", "#2A82E4");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", carNo + "(" + DateUtil.convertString(new Date(), "HH时mm分") + ")");
        keyword1.put("color", "#2A82E4");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", supplier);
        keyword2.put("color", "#2A82E4");
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", orderId);
        keyword3.put("color", "#2A82E4");
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", material);
        keyword4.put("color", "#2A82E4");
        JSONObject keyword5 = new JSONObject();
        keyword5.put("value", weight);
        keyword5.put("color", "#2A82E4");
        JSONObject remarkJson = new JSONObject();
        remarkJson.put("value", remark);
        remarkJson.put("color", "#ED5024");
        JSONObject data = new JSONObject();
        data.put("first", first);
        data.put("keyword1", keyword1);
        data.put("keyword2", keyword2);
        data.put("keyword3", keyword3);
        data.put("keyword4", keyword4);
        data.put("keyword5", keyword5);
        data.put("remark", remarkJson);

        json.put("access_token", token);
        json.put("touser", openid);
        json.put("data", data);
//        json.put("access_token", token);
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            log.error("-----发送微信小程序过磅文本消息完成-------：" + res);
            if(obj.getInteger("errcode") == 0){//成功
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 42001 || obj.getInteger("errcode") == 40001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendWeightMessageV1(openid, title, carNo, supplier, orderId, material, weight, remark);
            } else {
                log.error("发送微信小程序过磅文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序过磅文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }

    /**
     * 发送微信小程序排队文本消息(服务模板)
     * @param openid openid
     * @param title 标题
     * @param remark 备注
     * @return
     */
    public static Integer sendServiceLineMessage(String openid, String accountOpenid, String title, String carNo, String business,
                                                             String line, String code, String remark) {
//        String token = "72_giYGCWYb9n2MwNrvfYrDDmRCBToIDsoRl4JLICYknLuZrWM1gEOpRphTJ1cHYQ5UTEzKieAV6YaGHdz1biUodBGWRYEiymSFUPMv0uGtV1VWr9ebny16RKlPmloDYZeAHAVQR";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
        json.put("template_id", "2_GMoc389gjc4b9VZ4MiYKQ9OCMC1dMdn-G-vFwA5_I");
        json.put("url", "https://order.chixugroup.com/wechat/driver/vehicle/wait?openid=" + openid);
        json.put("appid", WechatAccountApi.account_appid);

        JSONObject first = new JSONObject();
        first.put("value", title);
        first.put("color", "#2A82E4");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", carNo);
        keyword1.put("color", "#2A82E4");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", business);
        keyword2.put("color", "#2A82E4");
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", line);
        keyword3.put("color", "#2A82E4");
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", code);
        keyword4.put("color", "#2A82E4");
        JSONObject keyword5 = new JSONObject();
        keyword5.put("value", DateUtil.convertString(new Date(), "yyyy年MM月dd日 HH时mm分"));
        keyword5.put("color", "#2A82E4");
        JSONObject remarkJson = new JSONObject();
        remarkJson.put("value", remark);
        remarkJson.put("color", "#ED5024");
        JSONObject data = new JSONObject();
        data.put("first", first);
        data.put("keyword1", keyword1);
        data.put("keyword2", keyword2);
        data.put("keyword3", keyword3);
        data.put("keyword4", keyword4);
        data.put("keyword5", keyword5);
        data.put("remark", remarkJson);

        json.put("access_token", token);
        json.put("touser", accountOpenid);
        json.put("data", data);
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            log.error("-----发送微信小程序排队文本消息完成-------：" + res);
            if(obj.getInteger("errcode") == 0){
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 42001 || obj.getInteger("errcode") == 40001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendServiceLineMessage(openid, accountOpenid, title, carNo, business, line, code, remark);
            } else {
                log.error("发送微信小程序排队文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序排队文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }

    /**
     * 发送微信小程序文本消息(异常过磅模板)
     * @param openid
     * @param message 错误消息
     * @param carNo 车牌
     * @param detailUrl
     * @return
     */
    public static Integer sendWeightErrorMessage(String openid, String message, String carNo, String detailUrl) {
//        String token = "72_giYGCWYb9n2MwNrvfYrDDmRCBToIDsoRl4JLICYknLuZrWM1gEOpRphTJ1cHYQ5UTEzKieAV6YaGHdz1biUodBGWRYEiymSFUPMv0uGtV1VWr9ebny16RKlPmloDYZeAHAVQR";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
        json.put("template_id", "gHZ85X7Aft39Ye-tzikQDRHumMYW5cJFMFCjFLzFB4o");
        if (!StringUtils.isNull(detailUrl))
            json.put("url", detailUrl);
        else
            json.put("url", "http://weixin.qq.com/download");
        json.put("appid", WechatAccountApi.account_appid);

        JSONObject first = new JSONObject();
        first.put("value", message);
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", message);
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", carNo);
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", DateUtil.convertString(new Date(), "yyyy年MM月dd日 HH:mm"));
        JSONObject remark = new JSONObject();
        remark.put("value", message);
        JSONObject data = new JSONObject();
        data.put("first", first);
        data.put("keyword1", keyword1);
        data.put("keyword2", keyword2);
        data.put("keyword3", keyword3);
        data.put("remark", remark);

        json.put("access_token", token);
        json.put("touser", openid);
        json.put("data", data);
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            if(obj != null && obj.getInteger("errcode") == 0){
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 40001 || obj.getInteger("errcode") == 42001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendWeightErrorMessage(openid, message, carNo, detailUrl);
            } else {
                log.error("发送微信小程序文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }

    /**
     * 发送微信小程序文本消息(服务模板)
     * @param openid openid
     * @param keyList key列表
     * @param valueList 发送值列表
     * @return
     */
    public static Integer sendWehcatOrderMessage(String openid, String templateId, List<String> keyList, List<String> valueList,
                                                 String detailUrl) {
//        String token = "78_Sa-HEpIAK4VgvK8PJZEBz3rjKLVPspRfFWz4ZHy-jOxIiWbNE7EezoanjVqqddHMBF5ndzXP-9XBVMSy-njSq6ublIF4gJE0f5_If7DEvQ5z7w-XCYrjoQyXExoQWViAJAYED";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
        json.put("template_id", templateId);
        if (!StringUtils.isNull(detailUrl))
            json.put("url", detailUrl);
        else
            json.put("url", "http://weixin.qq.com/download");
        json.put("appid", WechatAccountApi.account_appid);
        if (keyList == null || keyList.size() == 0 || valueList == null
                || valueList.size() == 0 || keyList.size() != valueList.size())
            return null;
        JSONObject data = new JSONObject();
        for (int i = 0; i < keyList.size(); i++) {
            JSONObject keyJson = new JSONObject();
            keyJson.put("value", valueList.get(i));
            data.put(keyList.get(i), keyJson);
        }

        json.put("access_token", token);
        json.put("touser", openid);
        json.put("data", data);
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            if(obj != null && obj.getInteger("errcode") == 0){
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 40001 || obj.getInteger("errcode") == 42001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendWehcatOrderMessage(openid, templateId, keyList, valueList, detailUrl);
            } else {
                log.error("发送微信小程序文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }
    /**
     * 发送微信小程序文本消息(服务模板)
     * @param openid openid
     * @param content 内容
     * @param title 标题
     * @param remark 备注
     * @return
     */
    public static Integer sendServiceMessage(String openid, String title, String titleColor, String content,
                                                         String contentColor, String remark, String remarkColor, String detailUrl) {
//        String token = "72_giYGCWYb9n2MwNrvfYrDDmRCBToIDsoRl4JLICYknLuZrWM1gEOpRphTJ1cHYQ5UTEzKieAV6YaGHdz1biUodBGWRYEiymSFUPMv0uGtV1VWr9ebny16RKlPmloDYZeAHAVQR";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
        json.put("template_id", "q3XpNco1duT9Z7H3MbrV3DXLPKR4DKSOqxq-wfeha-0");
        if (!StringUtils.isNull(detailUrl))
            json.put("url", detailUrl);
        else
            json.put("url", "http://weixin.qq.com/download");
        json.put("appid", WechatAccountApi.account_appid);

        JSONObject first = new JSONObject();
        first.put("value", title);
        if (!StringUtils.isNull(titleColor))
            first.put("color", titleColor);
        else
            first.put("color", "#2A82E4");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", content);
        if (!StringUtils.isNull(contentColor))
            keyword1.put("color", contentColor);
        else
            keyword1.put("color", "#2A82E4");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", DateUtil.convertString(new Date(), "yyyy年MM月dd日 HH时mm分"));
        keyword2.put("color", "#2A82E4");
        JSONObject remarkJson = new JSONObject();
        remarkJson.put("value", remark);
        if (!StringUtils.isNull(remarkColor))
            remarkJson.put("color", remarkColor);
        else
            remarkJson.put("color", "#ED5024");
        JSONObject data = new JSONObject();
        data.put("first", first);
        data.put("keynote1", keyword1);
        data.put("keynote2", keyword2);
        data.put("remark", remarkJson);

        json.put("access_token", token);
        json.put("touser", openid);
        json.put("data", data);
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            if(obj != null && obj.getInteger("errcode") == 0){
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 40001 || obj.getInteger("errcode") == 42001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendServiceMessage(openid, title, titleColor, content, contentColor, remark, remarkColor, detailUrl);
            } else {
                log.error("发送微信小程序文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }

    /**
     * 发送微信小程序文本消息(服务模板)
     * @param openid openid
     * @param content 内容
     * @param title 标题
     * @param remark 备注
     * @return
     */
    public static Integer sendWaringServiceMessage(String openid, String title, String content, String name,
                                                               String remark, String detailUrl) {
//        String token = "72_giYGCWYb9n2MwNrvfYrDDmRCBToIDsoRl4JLICYknLuZrWM1gEOpRphTJ1cHYQ5UTEzKieAV6YaGHdz1biUodBGWRYEiymSFUPMv0uGtV1VWr9ebny16RKlPmloDYZeAHAVQR";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
        json.put("template_id", "gHZ85X7Aft39Ye-tzikQDRHumMYW5cJFMFCjFLzFB4o");
        if (!StringUtils.isNull(detailUrl))
            json.put("url", detailUrl);
        else
            json.put("url", "http://weixin.qq.com/download");
        json.put("appid", WechatAccountApi.account_appid);

        JSONObject first = new JSONObject();
        first.put("value", title.trim());
        first.put("color", "#2A82E4");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", content.trim());
        keyword1.put("color", "#2A82E4");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", name.trim());
        keyword2.put("color", "#2A82E4");
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", DateUtil.convertString(new Date(), "yyyy年MM月dd日 HH时mm分"));
        keyword3.put("color", "#2A82E4");
        JSONObject remarkJson = new JSONObject();
        remarkJson.put("value", remark);
        remarkJson.put("color", "#ED5024");
        JSONObject data = new JSONObject();
        data.put("first", first);
        data.put("keyword1", keyword1);
        data.put("keyword2", keyword2);
        data.put("keyword3", keyword3);
        data.put("remark", remarkJson);

        json.put("access_token", token);
        json.put("touser", openid);
        json.put("data", data);
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            if(obj != null && obj.getInteger("errcode") == 0){
                map.put("errcode", obj.getString("errcode"));
                map.put("errmsg", obj.getString("errmsg"));
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 40001 || obj.getInteger("errcode") == 42001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendWaringServiceMessage(openid, title, content, name, remark, detailUrl);
            } else {
                log.error("发送微信小程序文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }

    /**
     *  获取微信公众号的token
     */
    public static String getAccountToken() {
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            return StringUtils.convertString(redisUtils.get(accessTokenKey));
        }
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + account_appid + "&secret=" + account_secret;
        try {
            String res = HttpRequestHelper.get(url);
            JSONObject obj = JSONObject.parseObject(res);
            if(!StringUtils.isNull(obj.getString("access_token"))){
                log.info("access_token=" + obj.getString("access_token"));
                redisUtils.set(accessTokenKey, obj.getString("access_token"), sessionExpired);
                return obj.getString("access_token");
            } else {
                log.error("获取微信公众号API token失败：" + res);
                return "";
            }
        } catch (Exception e) {
            log.error("获取微信公众号API token失败：" + e.getMessage(), e);
            return "";
        }
    }

    /**
     * 推送公众号过磅消息
     * @param openid 公众号openid
     * @param templateId 消息模板ID
     * @param toUrl 跳转URL
     * @param data 发送消息格式
     * @return
     */
    public static Integer sendWeightMessage(String openid, String templateId, String toUrl, JSONObject data) {
//        String token = "61_oOlPjxy2NYv_XkE4X6EgK6rYCs9P1B07_htD-5SUKIdZ44xQKvlQ0TcEzSADlspEEeQrgfbYzjI5KDP4yBwVLdIQ2HbHwhE_24LqpyWC0mFpznYfTuZD2bovGvmCbV88bgW5-BTpSDb61PKlPARbADASDU";
        String token = "";
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        if (redisUtils.exists(accessTokenKey)) {
            token = StringUtils.convertString(redisUtils.get(accessTokenKey));
        } else {
            token = getAccountToken();
        }

        if (StringUtils.isNull(token))
            return null;

        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token;
        JSONObject json = new JSONObject();
//        JSONObject template = new JSONObject();
        json.put("touser", openid);
        json.put("template_id", templateId);
        json.put("page", toUrl);
        json.put("appid", account_appid);
        json.put("data", data);

        System.out.println(json.toString());
        Map<String, Object> map = new HashMap<>();
        try {
            String res = HttpRequestHelper.senPostJson(url, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(res);
            System.out.println(res);
            log.error("-----发送微信公众号消息完成-------：" + res);
            if(obj.getInteger("errcode") == 0){
                return 0;
            } else if(obj.getInteger("errcode") == 43004){//需要关注
                return 1;
            } else if (obj.getInteger("errcode") == 42001 || obj.getInteger("errcode") == 40001
                    || obj.getInteger("errcode") == 41001) {
                redisUtils.remove(accessTokenKey);
                getAccountToken();
                return sendWeightMessage(openid, templateId, toUrl, data);
            } else {
                log.error("发送微信小程序排队文本消息失败：" + res);
                return -1;
            }
        } catch (Exception e) {
            log.error("发送微信小程序排队文本消息失败：" + e.getMessage(), e);
            return -1;
        }
    }

	/**
	 * 获取订阅号accessToken
	 * @return
	 */
	public static Map<String, Object> getUserAccessToken() {
		// 订阅号appid以及app_secret
		String appId = "wxc386d460ac006348";
		String secret = "01186b6db7e219dfdaac7b39c2a9ec06";
		// String appId = account_appid;
		// String secret = account_secret;
		/**判断ticket签名是否存在**/
		RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
		if (redisUtils.exists(appId)) {
			String s = StringUtils.convertString(redisUtils.get(appId));
			Map<String, Object> map = StringUtils.aliConvertMap(s);
			return map;
		}
		String url = "https://api.weixin.qq.com/cgi-bin/token" +
			"?appid=" + appId + "&secret=" + secret + "&grant_type=client_credential";
		try {
			String result = HttpRequestHelper.get(url);
			JSONObject json = JSONObject.parseObject(result);
			log.info("微信订阅号获取用户accessToken信息:" + result);
			if (!StringUtils.isNull(json.getString("access_token"))) {
				Map<String, Object> map = new HashMap<>();
				map.put("openid", json.getString("openid"));
				map.put("access_token", json.getString("access_token"));
				map.put("scope", json.getString("scope"));
				String s = StringUtils.aliConvertJSONObject(map);
				redisUtils.set(appId, s, sessionExpired);
				return map;
			}
			return null;
		} catch (Exception e) {
			log.error("微信公众号获取用户 accessToken错误：" + e.getMessage());
			return null;
		}
	}

    /**
     * 根据授权CODE换取token
     * @param code
     * @return
     */
    public static Map<String, Object> getUserAccessToken(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=" + account_appid + "&secret=" + account_secret + "&code=" + code + "&grant_type=authorization_code";
        try {
            String result = HttpRequestHelper.get(url);
            JSONObject json = JSONObject.parseObject(result);
            log.info("微信公众号获取用户accessToken信息:" + result);
            if (!StringUtils.isNull(json.getString("access_token"))) {
                Map<String, Object> map = new HashMap<>();
                map.put("openid", json.getString("openid"));
                map.put("access_token", json.getString("access_token"));
                map.put("scope", json.getString("scope"));
                return map;
            }
            return null;
        } catch (Exception e) {
            log.error("微信公众号获取用户 accessToken错误：" + e.getMessage());
            return null;
        }
    }

    /**
     * 根据token获取用户信息
     * @param webToken
     * @param openid
     * @return
     */
    public static Map<String, Object> getUserInfo(String webToken, String openid) {
        if (StringUtils.isAllParamNull(webToken, openid))
            return null;
        try {
            String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + webToken + "&openid=" + openid + "&lang=zh_CN";
            String result = HttpRequestHelper.get(url);
            JSONObject json = JSONObject.parseObject(result);
            log.info("微信公众号获取用户信息getUserInfo错误:" + result);
            if (!StringUtils.isNull(json.getString("nickname"))) {
                Map<String, Object> map = new HashMap<>();
                map.put("openid", json.getString("openid"));
                map.put("nickname", json.getString("nickname"));
                map.put("sex", json.getInteger("sex"));
                map.put("headimgurl", json.getString("headimgurl"));//头像
                map.put("city", json.getString("city"));//城市
                map.put("province", json.getString("province"));//省份
                map.put("unionid", json.getString("unionid"));
                map.put("privilege", json.getString("privilege"));//授权用户信息
                return map;
            }
            return null;
        } catch (Exception e) {
            log.error("微信公众号获取用户信息错误：" + e.getMessage());
            return null;
        }
    }

    /**
     * 获取公众号的JS_Ticket
     * @return
     */
    public static String getJsTicket() {
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        /**判断ticket签名是否存在**/
        if (redisUtils.exists(ticketKey)) {
            return StringUtils.convertString(redisUtils.get(ticketKey));
        }
        String accessToken = getAccountToken();
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";
        try {
            String res = HttpRequestHelper.get(url);
            JSONObject obj = JSONObject.parseObject(res);
            if(obj.getInteger("errcode") == 0 && !StringUtils.isNull(obj.getString("ticket"))){
                log.info("ticket=" + obj.getString("ticket"));
                redisUtils.set(ticketKey, obj.getString("ticket"), sessionExpired);
                return obj.getString("ticket");
            } else if (obj != null && obj.getInteger("errcode") == 40001) {
                redisUtils.remove(accessTokenKey);
                return getJsTicket();
            } else {
                log.error("获取微信公众号API JS_Ticket失败：" + res);
                return "";
            }
        } catch (Exception e) {
            log.error("获取微信公众号API JS_Ticket失败：" + e.getMessage(), e);
            return "";
        }
    }

    /**
     * 微信公众号加密签名
     * @param nonceStr
     * @param url
     * @param ticket
     * @param timestamp
     * @return
     */
    public static String jsApiSignature(String nonceStr, String url, String ticket, Long timestamp){
        String str = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url="+url;
        log.error("jsApiSign sinStr:" + str);
        String signature = sha1(str).toLowerCase();
        log.error("jsApiSign signature:" + signature);
        return signature;
    }

    /**
     * sha1签名
     * @param str
     */
    public static String sha1(String str){
        MessageDigest md = null;
        String tmpStr = null;
        try {
            md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(str.getBytes("utf-8"));
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return tmpStr;
    }

    /**
     * 将字节数组转换为十六进制字符串
     * @param byteArray
     * @return
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }

    /**
     * 将字节转换为十六进制字符串
     * @param mByte
     * @return
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];

        String s = new String(tempArr);
        return s;
    }
}
